package com.zff.rental.service.apartment;


import com.zff.rental.common.BusinessException;
import com.zff.rental.common.PageVo;
import com.zff.rental.common.ResultCode;
import com.zff.rental.entity.apartment.AttachmentEntity;
import com.zff.rental.entity.apartment.SuitesTypeEntity;
import com.zff.rental.mapstruct.apartment.AttachmentMapstruct;
import com.zff.rental.mapstruct.apartment.SuitesTypeMapstruct;
import com.zff.rental.service.BaseService;
import com.zff.rental.utils.specification.SpecBuilder;
import com.zff.rental.vo.apartment.attachment.AttachmentVo;
import com.zff.rental.vo.apartment.suites.AddSuitesTypeParams;
import com.zff.rental.vo.apartment.suites.ModifySuitesTypeParams;
import com.zff.rental.vo.apartment.suites.SuitesTypeListParams;
import com.zff.rental.vo.apartment.suites.SuitesTypeVo;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;

/**
 * @author HCY
 */
@Service
public class SuitesTypeServer extends BaseService {

    @Transactional
    public SuitesTypeVo add(AddSuitesTypeParams params) {
        SuitesTypeEntity map = SuitesTypeMapstruct.INSTANCE.map(params);
        if (suitesTypeRepository.existsByApartmentIdAndName(map.getApartmentId(), map.getName())) {
            throw new BusinessException("套间名称已存在");
        }

        SuitesTypeEntity saveResult = suitesTypeRepository.save(map);
        SuitesTypeVo vo = SuitesTypeMapstruct.INSTANCE.map(saveResult);

        // 保存附件
        Long id = saveResult.getId();
        List<AttachmentEntity> attachmentList = AttachmentMapstruct.INSTANCE.map(params.getAttachmentList(), id, 3);
        if (attachmentList.size() > 0) {
            List<AttachmentEntity> saveAttachmentList = attachmentRepository.saveAll(attachmentList);
            vo.setAttachmentList(AttachmentMapstruct.INSTANCE.map(saveAttachmentList));
        }

        return vo;
    }

    @Transactional
    public SuitesTypeVo modify(ModifySuitesTypeParams params) {
        Long id = params.getId();
        SuitesTypeEntity findResult = suitesTypeRepository.findById(id).orElseThrow(ResultCode.RECORD_NOT_EXISTS::toException);
        if (findResult == null) {
            throw ResultCode.RECORD_NOT_EXISTS.toException();
        }
        SuitesTypeMapstruct.INSTANCE.merge(findResult, params);
        SuitesTypeEntity saveResult = suitesTypeRepository.save(findResult);

        SuitesTypeVo vo = SuitesTypeMapstruct.INSTANCE.map(saveResult);

        // 修改附件
        List<AttachmentEntity> saveAttachmentList = attachmentRepository.saveAllOrDelete(params.getAttachmentList(), id, 3);
        vo.setAttachmentList(AttachmentMapstruct.INSTANCE.map(saveAttachmentList));

        return vo;
    }

    public Boolean remove(Long id) {
        suitesTypeRepository.deleteById(id);
        return true;
    }

    public SuitesTypeVo details(Long id) {
        SuitesTypeEntity findResult = suitesTypeRepository.findById(id).orElseThrow(ResultCode.RECORD_NOT_EXISTS::toException);
        if (findResult == null) {
            throw ResultCode.RECORD_NOT_EXISTS.toException();
        }
        SuitesTypeVo vo = SuitesTypeMapstruct.INSTANCE.map(findResult);

        List<AttachmentEntity> attachmentEntityList = attachmentRepository.findAllByBelongIdAndBelongType(id, 3);
        attachmentEntityList.sort(Comparator.comparingInt(e -> e.getSerialNumber() == null ? Integer.MAX_VALUE : e.getSerialNumber()));
        List<AttachmentVo> attachmentList = AttachmentMapstruct.INSTANCE.map(attachmentEntityList);
        vo.setAttachmentList(attachmentList);

        return vo;
    }

    public PageVo<SuitesTypeVo> list(SuitesTypeListParams params) {
        Specification<SuitesTypeEntity> where = SpecBuilder.<SuitesTypeEntity>builder()
                .equal("apartmentId", params.getApartmentId())
                .buildAnd();

        Page<SuitesTypeEntity> pageResult = suitesTypeRepository.findAll(where, params.generatePageable());

        List<SuitesTypeEntity> records = pageResult.getContent();
        List<SuitesTypeVo> voList = SuitesTypeMapstruct.INSTANCE.mapAsList(records);

        return PageVo.of(pageResult, voList);
    }
}
